#include "AMCAXUtils.h"
#include "common/logger.h"
#include "topology/TopoBuilder.hpp"
#include "healing/ShapeFixTool.hpp"
#include "common/Precision.hpp"
#include <geometry/Geom3Curve.hpp>
#include <topology/TopoExplorerTool.hpp>
#include <topology/TopoTool.hpp>
#include <topology/TopoVertex.hpp>

AMCAX_EXCHANGE_NAMESPACE_BEGIN

namespace InterOp::AMCAXTopoTools {

void CombineShapes(AMCAX::TopoShape &firstShape, AMCAX::TopoShape &secondShape, bool isFixed)
{
    if (
        secondShape.IsNull()
        || firstShape.IsNull()
    )
    {
        LOG_ERROR("first or second shape is null");
        return;
    }

    try
    {
        AMCAX::TopoBuilder TB;
        if (isFixed)
            secondShape = AMCAX::ShapeFixTool::FixShape(secondShape, AMCAX::Precision::Confusion(), 1e-4);
        TB.Add(firstShape, secondShape);
    }
    catch (const std::exception &e)
    {
        LOG_DEBUG("combine_shapes error:{}", e.what());
    }   
}


bool CheckEdgeCoincide(const AMCAX::TopoEdge& edge1, const AMCAX::TopoEdge& edge2, double tol)
{
    AMCAX::TopoVertex v1f, v1l, v2f, v2l;
    AMCAX::TopoExplorerTool::Vertices(edge1, v1f, v1l);
    AMCAX::TopoExplorerTool::Vertices(edge2, v2f, v2l);
    AMCAX::Point3 p11 = AMCAX::TopoTool::Point(v1f);
    AMCAX::Point3 p12 = AMCAX::TopoTool::Point(v1l);
    AMCAX::Point3 p21 = AMCAX::TopoTool::Point(v2f);
    AMCAX::Point3 p22 = AMCAX::TopoTool::Point(v2l);
    bool issame1121 = p11.Distance(p21) < tol;
    bool issame1222 = p12.Distance(p22) < tol;
    bool issame1122 = p11.Distance(p22) < tol;
    bool issame1221 = p12.Distance(p21) < tol;
    if ((issame1121 && issame1222) || (issame1122 && issame1221))
    {
        double param11, param12, param21, param22; 
        std::shared_ptr<AMCAX::Geom3Curve> curve1 = AMCAX::TopoTool::Curve(edge1, param11, param12);
        std::shared_ptr<AMCAX::Geom3Curve> curve2 = AMCAX::TopoTool::Curve(edge2, param21, param22);
        
        AMCAX::Point3 pmid1 = curve1->Value((param11 + param12) / 2);
        AMCAX::Point3 pmid2 = curve2->Value((param21 + param22) / 2);
        if (pmid1.Distance(pmid2) < tol)
        {
            return true;
        }
    }

    return false;
}

}

AMCAX_EXCHANGE_NAMESPACE_END